﻿namespace Mosquito.ViewModel.Collections {
    using System;
    using System.Collections.Generic;

    using Mosquito.ViewModel.Collections.Tree;

    public class SortedObservableTree<TKey, TKeyPart, TValue> :
        SortedObservableTreeBase<TKey, TKeyPart, TValue, SortedObservableTree<TKey, TKeyPart, TValue>> {

        private readonly Func<TKey, IEnumerable<TKeyPart>> splitKey;
        private readonly Func<IEnumerable<TKeyPart>, TKey> joinKey;

        public SortedObservableTree(
            Func<TKey, IEnumerable<TKeyPart>> splitKey,
            Func<IEnumerable<TKeyPart>, TKey> joinKey,
            IComparer<TKeyPart> comparer)
            : base(comparer) {
            if (splitKey == null) {
                throw new ArgumentNullException("splitKey");
            }

            if (joinKey == null) {
                throw new ArgumentNullException("joinKey");
            }

            this.splitKey = splitKey;
            this.joinKey = joinKey;
        }

        public SortedObservableTree(Func<TKey, IEnumerable<TKeyPart>> splitKey, Func<IEnumerable<TKeyPart>, TKey> joinKey) :
            this(splitKey, joinKey, Comparer<TKeyPart>.Default) { }

        public new void Add(TKey relativeKey, TValue item) {
            base.Add(relativeKey, item);
        }

        public new void Remove(TKey relativeKey) {
            base.Remove(relativeKey);
        }

        public new void Remove(TKey relativeKey, TValue item) {
            base.Remove(relativeKey, item);
        }

        protected override SortedObservableTree<TKey, TKeyPart, TValue> CreateNode() {
            return new SortedObservableTree<TKey, TKeyPart, TValue>(this.splitKey, this.joinKey, this.comparer) {
                Parent = this
            };
        }

        protected override IEnumerable<TKeyPart> SplitKey(TKey key) {
            return this.splitKey(key);
        }

        protected override TKey JoinKey(IEnumerable<TKeyPart> keyParts) {
            return this.joinKey(keyParts);
        }
    }
}
